﻿#ifndef _FD_MODELDATASOURCE_H_
#define _FD_MODELDATASOURCE_H_ 

#include "../dll_cfg.h"
#include "kernel/threading/mutex.h"
#include "udatabase/sqldatabase.h"
#include "udatabase/spatialDB/sqlstandardization.h"
#include "udatabase/spatialDB/databasedatasource.h"

namespace FD
{
	namespace Utility
	{
		namespace DB
		{
			class CSqlstandardization;
			namespace Interface
			{
				class IDataMetaInfos;
				class IDataMetaInfo;
				class IFeatureClass;
				class IFields;
			}
		}
	}
}

namespace FD
{
	namespace Utility
	{
		namespace Dataset
		{
			class ModelDB;
			class ModelDBFeatureClass;

			struct ModelDBInfo
			{
				String dbName;
				uint32 dbID;

				ModelDBInfo()
				{
					dbID = 0;
				}
			};

			class FD_XDataset_Export ModelDataSource : public FD::Utility::DB::CDatabaseDataSource
			{
				friend class ModelDataSourceManager;
			public:
				static String DEFAULT_MODELDB_NAME;
				static String getPostFixName(INT32 tid);


				/**********************************基础信息***********************************/
				bool isOffLine(); 

				String getName() const;

				virtual INT32 initialize();

				FD::Utility::DB::CSqlstandardization* getSqlStd(){return sqlStd;}

#ifndef FDB_LINUX
				/**********************************数据集相关***********************************/

				FD::Utility::DB::Interface::IDataMetaInfos* getDatasetInfos();

				FD::Utility::DB::Interface::IDataMetaInfo* getDatasetInfo(const String& name);

				bool updateMetaInfo(String datasetName,FD::Utility::DB::Interface::IDataMetaInfo* info);

				INT32 insertMetaInfo(FD::Utility::DB::Interface::IDataMetaInfo* info);

				void deleteMetaInfo(INT32 tid);

				INT32 existMetaInfo(const String& name);

				FD::Utility::DB::Interface::IFeatureClass * createFeatureClass(const String& name, const String& sr, FD::Utility::DB::Interface::IFields* attrs);

				void deleteFeatureClass(const String& name);

				FD::Utility::DB::Interface::IFeatureClass * openFeatureClass(const String& name);

				void closeFeatureClass(FD::Utility::DB::Interface::IFeatureClass*);				

				/**********************************模型库*********************************/
#endif
				void getModelDBList(std::vector<ModelDBInfo>& list);
				uint32 createModelDB(const String& dbName);
				void deleteModelDB(const String& dbName);

				uint32 getModelDBID(const String& dbName);
				String getModelDBName(uint32 dbid);

				ModelDB* getModelDB(const String& dbName);
				ModelDB* getModelDB(uint32 dbid);
				ModelDB* getModelDB();

			protected:
				ModelDataSource(const FD::Utility::DB::CSqlDatabase &db, const String& dbType, ModelDBSourceType type);
				virtual ~ModelDataSource();

				C_DISABLE_COPY(ModelDataSource);

				static bool openDataSource(ModelDBSourceType type
								,const String& host
								,UINT32 port
								,const String& dbName
								,const String& user
								,const String& password, FD::Utility::DB::CSqlDatabase& db);

				static bool openDataSource(const String& dbfile, FD::Utility::DB::CSqlDatabase& db);
#ifndef FDB_LINUX
				FD::Utility::DB::Interface::IDataMetaInfo* getDatasetInfo(const String& name, bool& fromCache);

				bool createFeatureClassTab(const String& tid, FD::Utility::DB::Interface::IFields* attrs);
				void deleteFeatureClassTab(const String& tid);

				bool createModelTab(const String& tid, FD::Utility::DB::Interface::IFields* attrs);
				void deleteModelTab(const String& tid);

				bool createModelGeomTab(const String& tid);
				void deleteModelGeomTab(const String& tid);

				bool createModelMetaInfoTab(const String& tid);
				void deleteModelMetaInfoTab(const String& tid);

				bool createModelSemanticTab(const String& tid);
				void deleteModelsemanticTab(const String& tid);
#endif
				bool createTab(const String& sqlScript);
				bool createModelDBTab(const String& tid);
				void deleteModelDBTab(const String& tid);

				bool createLinearTab();
				void deleteLinearTab();

				bool createLockTab();
				void deleteLockTab();

				bool existsModelDB(const String& name);

				

			private:
				bool mbOffLine;			
				typedef std::map<uint32, ModelDB*> ModelDBList;
				ModelDBList mModelDBList;
			};

			class FD_XDataset_Export ModelDataSourceManager
			{
			protected:
				ModelDataSourceManager();

				C_DISABLE_COPY(ModelDataSourceManager);

			protected:

				static ModelDataSourceManager* mpSingleton;
				static FD::Kernel::RecursiveMutex mInstanceMutex;

				struct SourceItem
				{
					ModelDataSource* pSource;
					UINT16 refCount;
				};

				typedef std::map<String, SourceItem>  ModelSourceMap;
				ModelSourceMap mSourceMap;
				FD::Kernel::RecursiveMutex mSourceMutex;
			public:

				static ModelDataSourceManager* getSingletonPtr();

				static void releaseSingleton();

				ModelDataSource* openDataSource(ModelDBSourceType type
											,const String& host
											,UINT32 port
											,const String& dbName
											,const String& user
											,const String& password
											,bool mustOnline = false);

				static bool createSqliteSource(const String& dbfile);

				void closeDataSource(ModelDataSource* pSource);

			};

		}
	}
}


#endif
